package com.cpx.config;

import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.servlet.Filter;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Auther: PanBin
 * @Date: 2018-9-5 14:08
 * @Description: 权限校验框架shiro的配置文件
 * @Version: 1.0
 */
@Configuration
public class ShiroConfig {

    /**
     * @Author: PanBin
     * @Description: shiro的过滤器配置
     * @CreateDate: 2018-9-5 14:21
     * @Param [manager]
     * @Return org.apache.shiro.spring.web.ShiroFilterFactoryBean
     */
    @Bean(name = "shiroFilter")
    public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager manager) {
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        bean.setSecurityManager(manager);
        Map<String,Filter> filterMap = new LinkedHashMap();
        filterMap.put("roles",new CustomRolesAuthorizationFilter());
        filterMap.put("perms",new CustomPermsAuthorizationFilter());
        bean.setFilters(filterMap);
        bean.setLoginUrl("/manager/login.html");//配置登录的url，无登录跳转页面
        bean.setSuccessUrl("/index.ftl");      //登录成功的url
        bean.setUnauthorizedUrl("/manager/notPerm.html");//未授权界面;
        //配置访问权限
        LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        filterChainDefinitionMap.put("/login.html", "anon");
        filterChainDefinitionMap.put("/confirmLogin.html", "anon");
        /**不拦截静态资源*/
        filterChainDefinitionMap.put("/js/**", "anon");
        filterChainDefinitionMap.put("/css/**", "anon");
        filterChainDefinitionMap.put("/img/**", "anon");
        filterChainDefinitionMap.put("/font/**", "anon");
        filterChainDefinitionMap.put("/layui/**", "anon");
        /**授权*/
        /*filterChainDefinitionMap.put("/goods/**", "perms[商品信息]");*/
        /**登录之后拥有的权限*/
        /*filterChainDefinitionMap.put("/*.html", "authc");
        filterChainDefinitionMap.put("/*", "authc");
        filterChainDefinitionMap.put("/**", "authc");*/
        bean.setFilterChainDefinitionMap(filterChainDefinitionMap);
        return bean;
    }

    /**
     * @Author: PanBin
     * @Description: 配置自定义的密码比较器
     * @CreateDate: 2018-9-5 14:23
     * @Param []
     * @Return com.cpx.config.CredentialsMatcher
     */
    @Bean(name = "credentialsMatcher")
    public CredentialsMatcher credentialsMatcher() {
        return new CredentialsMatcher();
    }

    /**
     * @Author: PanBin
     * @Description: 配置自定义的权限登录器
     * @CreateDate: 2018-9-5 14:23
     * @Param [matcher]
     * @Return com.cpx.config.AuthRealm
     */
    @Bean(name = "authRealm")
    public AuthRealm authRealm(@Qualifier("credentialsMatcher") CredentialsMatcher matcher) {
        AuthRealm authRealm = new AuthRealm();
        authRealm.setCredentialsMatcher(matcher);
        return authRealm;
    }

    /**
     * @Author: PanBin
     * @Description:  配置核心安全事务管理器
     * @CreateDate: 2018-9-5 14:23
     * @Param [authRealm]
     * @Return org.apache.shiro.mgt.SecurityManager
     */
    @Bean(name = "securityManager")
    public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm authRealm,@Qualifier("defaultWebSessionManager") DefaultWebSessionManager defaultWebSessionManager,@Qualifier("memoryConstrainedCacheManager") MemoryConstrainedCacheManager memoryConstrainedCacheManager) {
        DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
        manager.setRealm(authRealm);
        manager.setCacheManager(memoryConstrainedCacheManager);//缓冲
        manager.setSessionManager(defaultWebSessionManager);//session管理器
        return manager;
    }

    /**
     * @Author: PanBin
     * @Description: 配置shiro的内存缓存
     * @CreateDate: 2018-11-12 16:01
     * @Param []
     * @Return org.apache.shiro.cache.MemoryConstrainedCacheManager
     */
    @Bean(name = "memoryConstrainedCacheManager")
    public MemoryConstrainedCacheManager memoryConstrainedCacheManager() {
        return new MemoryConstrainedCacheManager();
    }

    @Bean("sessionDAO")
    public MemorySessionDAO sessionDAO() {
        return new MemorySessionDAO();
    }

    /**
     * @Author: PanBin
     * @Description:  配置shiro session 的一个管理器
     * @CreateDate: 2018-11-12 15:52
     * @Param [sessionDAO]
     * @Return org.apache.shiro.web.session.mgt.DefaultWebSessionManager
     */
    @Bean(name = "defaultWebSessionManager")
    public DefaultWebSessionManager defaultWebSessionManager(@Qualifier("sessionDAO") MemorySessionDAO sessionDAO,@Qualifier("simpleCookie") SimpleCookie simpleCookie) {
        DefaultWebSessionManager defaultWebSessionManager = new DefaultWebSessionManager();
        defaultWebSessionManager.setGlobalSessionTimeout(1800000);
        defaultWebSessionManager.setDeleteInvalidSessions(true);
        defaultWebSessionManager.setSessionValidationSchedulerEnabled(true);
        defaultWebSessionManager.setSessionValidationInterval(1800000);
        defaultWebSessionManager.setSessionIdCookie(simpleCookie);
        defaultWebSessionManager.setSessionDAO(sessionDAO);
        return defaultWebSessionManager;
    }

    @Bean(name = "simpleCookie")
    public SimpleCookie simpleCookie() {
        SimpleCookie simpleCookie = new SimpleCookie();
        simpleCookie.setName("SHRIOSESSIONID");
        return simpleCookie;
    }

    /**
     * @Author: PanBin
     * @Description: spring AOP自动代理
     * @CreateDate: 2018-11-8 17:24
     * @Param []
     * @Return org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(@Qualifier("securityManager") SecurityManager manager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(manager);
        return advisor;
    }

    /**
     * @Author: PanBin
     * @Description: 管理shiro bean的生命周期
     * @CreateDate: 2018-11-8 17:23
     * @Param []
     * @Return org.apache.shiro.spring.LifecycleBeanPostProcessor
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }

    @Bean
    public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator creator = new DefaultAdvisorAutoProxyCreator();
        creator.setProxyTargetClass(true);
        return creator;
    }
}
